package example.documentbased.editorModule.mediators
{
	import example.documentbased.editorModule.common.MenuItem;
	import example.documentbased.editorModule.controller.IEditorController;
	import example.documentbased.editorModule.models.EditorModuleModel;
	import example.documentbased.editorModule.views.IEditorModuleViewContract;
	import example.documentbased.mainModule.mediations.EditorsFacade;
	import example.documentbased.mainModule.models.vo.DocumentVO;
	import example.documentbased.mainModule.models.vo.EditorVO;
	
	import mx.collections.ArrayList;
	import mx.core.IDataRenderer;
	import mx.events.MenuEvent;
	import mx.utils.ObjectUtil;
	
	import org.etherframework.common.utils.OU;
	import org.etherframework.mediator.Mediator;
	
	public class EditorModuleViewMediator extends Mediator implements IEditorModuleViewContract
	{
		private var _openedDocuments:ArrayList;
		private var _editorController:IEditorController;
		private var _selectedItem:*;
		private var _menuItems:Array;
		private var _editorModel:EditorModuleModel;
		private var _editorsFacade:EditorsFacade;
		private var _color:uint;
		private var _editorName:String;

		public function EditorModuleViewMediator(editorModel:EditorModuleModel, 
												 editorController:IEditorController, 
												 editorsFacade:EditorsFacade) 
		{
			_editorModel = editorModel;
			_editorController = editorController;
			_editorsFacade = editorsFacade;
		}
		
		override public function complete():void
		{
			ether.mediations.bind.property(_editorModel.editor, 
				mEditorHandler);
			ether.mediations.bind.property(_editorModel.openedDocuments, 
				mOpenedDocumentsHandler);
			ether.mediations.bind.method(_editorModel.openDocument(null), 
				mOpenDocumentHandler);
			ether.mediations.bind.method(_editorModel.closeDocument(null), 
				mCloseDocumentHandler);
			ether.mediations.bind.property(_editorModel.currentDocument, 
				mCurrentDocumentHandler);
			ether.mediations.bind.property(_editorModel.lastSavedDocument, 
				mLastSavedDocumentHandler);
			ether.mediations.bind.method(_editorModel.editDocument(null), 
				mEditDocumentHandler);
			ether.mediations.bind.method(_editorsFacade.getEditorModel(null),
				mGetEditorModelHandler);
			ether.mediations.bind.property(_editorModel.menuItems,
				mMenuItemsHandler);
			
			_editorController.getUpdateEditorMenuCommand().execute();
			
			if (view is IDataRenderer)
				bindView("data", dataChangeHandler);
		}
		
		public function colorChanged(color:uint):void
		{
			var update:EditorVO = ObjectUtil.clone(_editorModel.editor) as EditorVO;
			update.color = color;
			_editorController.getSaveEditorCommand(update).execute();
		}
		
		public function nameClicked():void
		{
			_editorController.getChangeEditorNameCommand(_editorModel.editor).execute();
		}
		
		public function menuItemClicked(event:MenuEvent):void
		{
			if (!_editorModel.editor)
				return;
			
			_editorController.getApplyMenyItemCommand(MenuItem(event.item)).execute();
		}
		
		private function dataChangeHandler(value:EditorVO):void
		{
			_editorController.getSetEditorCommand(value).execute();
		}
		
		private function mEditorHandler(item:EditorVO):void
		{
			color = item ? item.color : 0x000000;
			editorName = item ? item.name : "";
			
			updateOpenedDocuments();
		}
		
		private function mOpenedDocumentsHandler(items:ArrayList):void
		{
			openedDocuments = ObjectUtil.clone(items) as ArrayList;
		}
		
		private function mOpenDocumentHandler(item:DocumentVO):void
		{
			_openedDocuments.addItem(item);
		}
		
		private function mCloseDocumentHandler(item:DocumentVO):void
		{
			var document:DocumentVO = OU.getItem(
				_openedDocuments, "uid", item.uid) as DocumentVO;
			
			if (document)
			{
				_openedDocuments.removeItem(document);
			}
		}
		
		private function mCurrentDocumentHandler(item:DocumentVO):void
		{
			if (item && !OU.areEqual(selectedItem, item, "uid"))
			{
				var document:DocumentVO = OU.getItem(
					_openedDocuments, "uid", item.uid) as DocumentVO;
				
				if (document && _openedDocuments.length > 1)
				{
					selectedItem = document;
				}
			}
			else if (!item)
			{
				selectedItem = null;
			}
			_editorController.getUpdateEditorMenuCommand().execute();
		}
		
		private function mLastSavedDocumentHandler(item:DocumentVO):void
		{
			if (item)
			{
				var document:DocumentVO = OU.getItem(
					_openedDocuments, "uid", item.uid) as DocumentVO;
				
				if (document)
				{
					document.apply(item);
					_openedDocuments.itemUpdated(document);
				}
			}
			_editorController.getUpdateEditorMenuCommand().execute();
		}
		
		private function mGetEditorModelHandler(id:String):EditorModuleModel
		{
			return (id == _editorModel.editor.id) ? _editorModel : null;
		}
		
		private function mEditDocumentHandler(value:DocumentVO):void
		{
			var document:DocumentVO = OU.getItem(
				_openedDocuments, "uid", value.uid) as DocumentVO;
			
			_openedDocuments.itemUpdated(document);
			_editorController.getUpdateEditorMenuCommand().execute();
		}
		
		private function mMenuItemsHandler(items:Array):void
		{
			menuItems = items;
		}
		
		private function updateOpenedDocuments():void
		{
			var editor:EditorVO = _editorModel.editor;
			
			if (editor && _openedDocuments && _openedDocuments.length)
			{
				var openedDoc:DocumentVO;
				var updateDoc:DocumentVO;
				const uidField:String = "uid";
				
				for (var i:int = 0; i < _openedDocuments.length; ++i)
				{
					openedDoc = _openedDocuments.getItemAt(i) as DocumentVO;
					updateDoc = OU.getItem(editor.documents, 
						uidField, openedDoc.uid) as DocumentVO;
					
					if (updateDoc)
					{
						openedDoc.apply(updateDoc);
						_openedDocuments.itemUpdated(openedDoc);
					}
					else if (openedDoc.id)
					{
						_openedDocuments.removeItem(openedDoc);
					}
				}
			}
		}
		
		[Bindable]
		public function get color():uint { return _color; }
		public function set color(value:uint):void { _color = value; }
		
		[Bindable]
		public function get editorName():String { return _editorName; }
		public function set editorName(value:String):void { _editorName = value; }
		
		[Bindable]
		public function get openedDocuments():ArrayList { return _openedDocuments; }
		public function set openedDocuments(value:ArrayList):void { _openedDocuments = value; }
		
		[Bindable]
		public function get menuItems():Array { return _menuItems; }
		public function set menuItems(value:Array):void { _menuItems = value; }
		
		[Bindable]
		public function get selectedItem():* { return _selectedItem; }
		public function set selectedItem(value:*):void 
		{
			_selectedItem = value;
			
			if (_selectedItem && !OU.areEqual(_editorModel.currentDocument, _selectedItem, "uid")) 
			{
				_editorController.getSetCurrentDocumentCommand(_selectedItem as DocumentVO).execute();
			}
		}
	}
}